/**
  * @file 		export.h
  * @brief		主要定义设备层挂载接口、APP层挂载接口、TASK挂载接口等SECTION相关重要宏定义。
  *
  * @copyright  Copyright (c) 2017~2020 ShenZhen Dxtc Technology Co., Ltd. 
  * All rights reserved.
  * 
  * @version    v3.1
  * @author		FengLi
  * @date 		2021-08-02
  * 
  * @note		鼎新同创·智能锁
  * 
  * @par 修改日志:
  * <1> 2021/08/02 v3.1 FengLi 创建初始版本
  *******************************************************************/
#ifndef __EXPORT_H__
#define __EXPORT_H__
#include <stdint.h>


/** @brief   定义设备层初始化函数指针类型 */
typedef void (*Device_Init_fn_t)(void);

/** @brief   设备驱动挂载接口（设备层入口函数导出接口） */
#define DEVICE_INIT_FN_EXPORT(fn, level)    __attribute__((used)) const Device_Init_fn_t __Hwl_Init_##fn __attribute__((section(".device_init_fn." level))) = fn
#define DEVICE_START_EXPORT(fn)             DEVICE_INIT_FN_EXPORT(fn, "0") ///< 用来挂载设备层第一个入口函数 -OS内部使用
#define INIT_BOARD_EXPORT(fn)               DEVICE_INIT_FN_EXPORT(fn, "1") ///< 用来挂载一个设备层的入口函数（高优先级）-用户挂载接口
#define INIT_PREV_EXPORT(fn)                DEVICE_INIT_FN_EXPORT(fn, "2") ///< 用来挂载一个设备层的入口函数（中优先级）-用户挂载接口
#define INIT_DEVICE_EXPORT(fn)              DEVICE_INIT_FN_EXPORT(fn, "3") ///< 用来挂载一个设备层的入口函数（低优先级）-用户挂载接口
#define DEVICE_END_EXPORT(fn)               DEVICE_INIT_FN_EXPORT(fn, "4") ///< 用来挂载设备层最后一个入口函数 -OS内部使用


/** @brief   定义APP初始化函数指针类型 */
typedef void (*App_Init_fn_t)(uint32_t, uint32_t);

/** @brief   APP层入口函数挂载接口（应用层主函数导出接口） */
#define APP_INIT_FN_EXPORT(fn, level)           __attribute__((used)) const App_Init_fn_t __App_Init_##fn __attribute__((section(".app_init_fn." level))) = fn
#define APP_INIT_START_EXPORT(fn)               APP_INIT_FN_EXPORT(fn, "1") ///< 用来挂载APP层第一个入口函数 -OS内部使用
#define APP_INIT_EXPORT(fn)                     APP_INIT_FN_EXPORT(fn, "2") ///< 用来挂载应用层入口函数 -用户挂载接口
#define APP_INIT_END_EXPORT(fn)                 APP_INIT_FN_EXPORT(fn, "3") ///< 用来挂载APP层最后一个入口函数 -OS内部使用


/** @brief   定义TASK任务表结构体类型 */
typedef struct 
{
    uint32_t ComPonent_Task_ID;               ///< 组件-ID/TASK-ID
    uint32_t (*ComPonent_Task_FN)(uint32_t);  ///< 任务函数
    uint32_t nv_size;                         ///< 任务对应NV-SIZE
}ComPonent_TaskInfo_stu_t;

/** @brief   组件层TASK函数挂载接口（任务函数导出接口） */
#define COMPONENT_TASK_FN_EXPORT(fnID, fn, nv, level)     __attribute__((used)) const ComPonent_TaskInfo_stu_t __ComPonent_Task_##fn __attribute__((section(".component_task_fn." level))) = {fnID, fn, nv}
#define COMPONENT_TASK_START_EXPORT(fn)         COMPONENT_TASK_FN_EXPORT(0,    fn, 0,  "1") ///< 用来挂载组件层第一个TASK函数 -OS内部使用
#define COMPONENT_TASK_EXPORT(fnID, fn, nv)     COMPONENT_TASK_FN_EXPORT(fnID, fn, nv, "2") ///< 用来挂在TASK函数 -用户挂载接口
#define COMPONENT_TASK_END_EXPORT(fn)           COMPONENT_TASK_FN_EXPORT(0,    fn, 0,  "3") ///< 用来挂载组件层最后一个TASK函数 -OS内部使用


/** @brief   定义WAKEUP唤醒表结构体类型 */
typedef struct
{
    uint16_t comp_id;         ///< 组件ID（TASK-ID）
    int32_t (*cb)(uint32_t);  ///< 回调接口
    uint32_t irq_dev;         ///< 中断源
}ComPonent_Wakeup_stu_t;

/** @brief   组件层唤醒回调函数挂载接口（唤醒回调函数导出接口） */
#define COMPONENT_WAKEUP_FN_EXPORT(fnID, fn, dev, level)     __attribute__((used)) const ComPonent_Wakeup_stu_t __ComPonent_Wakeup_##fn##dev __attribute__((section(".component_wake_fn." level))) = {fnID, fn, dev}
#define COMPONENT_WAKEUP_START_EXPORT(fn)         COMPONENT_WAKEUP_FN_EXPORT(0,    fn, 0,   "1") ///< 用来挂载组件层第一个唤醒回调函数 -OS内部使用
#define COMPONENT_WAKEUP_EXPORT(fnID, fn, dev)    COMPONENT_WAKEUP_FN_EXPORT(fnID, fn, dev, "2") ///< 用来挂载唤醒回调 -用户挂载接口
#define COMPONENT_WAKEUP_END_EXPORT(fn)           COMPONENT_WAKEUP_FN_EXPORT(0,    fn, 0,   "3") ///< 用来挂载组件层最后一个唤醒回调函数 -OS内部使用


/** 
  * @brief    定义特殊RAM区域 
  * 
  * @details  NVRAM(non volatile ram)：用__NVRAM修饰的变量休眠状态下允许读写
  *           为了保证休眠唤醒RAM不丢失，休眠前会将该段的数据全部搬到芯片特殊RAM区域暂存，唤醒再将RAM数据恢复
  * 
  * @details  EFRAM(embedded flash ram)：用__EFRAM修饰的变量休眠状态下仅允许读
  *           为了保证休眠唤醒RAM不丢失，休眠前会将该段的数据全部搬到芯片内部FLASH区域暂存，唤醒再将RAM数据恢复
  * 
  * @details  GRAM(global ram)：用__GRAM修饰的变量，执行软复位前会将该段数据搬到芯片内部FLASH区域暂存，OS启动时再将RAM数据恢复
  *           __GRAM修饰的变量可以理解为BOOT镜像和APP镜像共用的变量，即全局RAM，用于多个镜像之间互相传递数据
  */
#ifdef NVRAM_DISABLE
#define NVRAM_SECTION(level)
#else
#define NVRAM_SECTION(level)  __attribute__((section(".nvram." level)))
#endif
#define __NVRAM_A             NVRAM_SECTION("1") ///< 用来修饰一个变量，将它分配到__NVRAM段的起始
#define __NVRAM               NVRAM_SECTION("2") ///< 用来修饰一个变量，将它分配到__NVRAM段区域
#define __NVRAM_B             NVRAM_SECTION("3") ///< 用来修饰一个变量，将它分配到__NVRAM段的末尾（__EFRAM段的起始）
#define __EFRAM               NVRAM_SECTION("4") ///< 用来修饰一个变量，将它分配到__EFRAM段区域
#define __NVRAM_C             NVRAM_SECTION("5") ///< 用来修饰一个变量，将它分配到__EFRAM段的末尾（__GRAM段的起始）
#define __GRAM                NVRAM_SECTION("6") ///< 用来修饰一个变量，将它分配到__GRAM段区域
#define __NVRAM_D             NVRAM_SECTION("7") ///< 用来修饰一个变量，将它分配到__GRAM段的末尾


#endif /* __EXPORT_H__ */
